package com.wilmer.TecherLessonPlan.listener;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse;
import com.wilmer.TecherLessonPlan.domain.YwLessonPlan;
import com.wilmer.TecherLessonPlan.domain.vo.ChatFinishVo;
import com.wilmer.TecherLessonPlan.domain.vo.LessonPlan;
import com.wilmer.TecherLessonPlan.mapper.YwLessonPlanMapper;
import com.wilmer.common.core.domain.model.LoginUser;
import com.wilmer.common.utils.SecurityUtils;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;

/**
 * @author hasn
 * 24425
 * sse流式输出listener
 */
@Component
@Data
@Slf4j
public class LessonSseStreamFastGptListener extends EventSourceListener {

    private long tokens;

    private String lesson = "";


    private SseEmitter sseEmitter;

    private LessonPlan lessonPlan;

    private LoginUser loginUser;

    YwLessonPlanMapper lessonPlanMapper;


    @Override
    public void onOpen(EventSource eventSource, Response response) {
        log.info("OpenAI建立sse连接...");
    }

    @SneakyThrows
    @Override
    public void onEvent(EventSource eventSource, String id, String type, String data) {
        log.info("OpenAI返回数据：{}", data);
        tokens += 1;
        // 读取Jso
        if ("[DONE]".equals(data)) {
            log.info("OpenAI返回数据结束了");
            //讲教案写入数据库
            YwLessonPlan ywLessonPlan = new YwLessonPlan();
            ywLessonPlan.setUserId(loginUser.getUserId());
            ywLessonPlan.setDeptId(loginUser.getDeptId());
            ywLessonPlan.setCreateBy("AI小默");
            ywLessonPlan.setCreateTime(new Date());
            ywLessonPlan.setLplanName(lessonPlan.getLessonPlanName());
            ywLessonPlan.setLplanMain(lesson);
             lessonPlanMapper.insertYwLessonPlan(ywLessonPlan);
            //关闭连接
            sseEmitter.complete();
            return;
        }
        ObjectMapper mapper = new ObjectMapper();
        ChatCompletionResponse completionResponse = mapper.readValue(data, ChatCompletionResponse.class);
        boolean finish = Objects.equals(completionResponse.getChoices().get(0).getFinishReason(), "stop");
        String content = completionResponse.getChoices().get(0).getDelta().getContent();
        //拼接教案
        lesson += content;
        try {
            if (finish) {
                sseEmitter.send(new ChatFinishVo());
            } else {
                sseEmitter.send(SseEmitter.event().data(completionResponse.getChoices().get(0).getDelta()));
            }


        } catch (Exception e) {
            log.error("sse信息推送失败！");
            eventSource.cancel();
        }
    }


    @Override
    public void onClosed(EventSource eventSource) {
        log.info("流式输出返回值总共{}tokens", tokens() - 2);
        log.info("OpenAI关闭sse连接...");
    }

    @SneakyThrows
    @Override
    public void onFailure(EventSource eventSource, Throwable t, Response response) {
        if (Objects.isNull(response)) {
            return;
        }
        ResponseBody body = response.body();
        if (Objects.nonNull(body)) {
            log.error("fastgpt sse连接异常data：{}，异常：{}", body.string(), t);
        } else {
            log.error("fastgpt  sse连接异常data：{}，异常：{}", response, t);
        }
        eventSource.cancel();
    }

    /**
     * tokens
     *
     * @return
     */
    public long tokens() {
        return tokens;
    }

}
